import Router from '@koa/router';
import logger from '../logger.js';
import response from '../response.js';
import { GetOpenID, getPhoneNumber } from '../common/wx.js';
import lsyPay from '../common/lsyPay.js';
import db from '../mysqlHelper.js';
import moment from 'moment';
import { getEMT, setEME } from '../meter.js';

const router = new Router();
router.prefix('/api');

router.post(`/applet/getOpenID`, async (ctx) => {
    let body = ctx.request.body;
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if (body.code == null) {
        ctx.body = response.fail('缺少必填字段 code');
        return;
    }
    let res = await GetOpenID(body.code);
    if (res.code == 1) {
        ctx.body = response.fail(res.msg);
        return;
    }
    ctx.body = response.success(res.data, '获取OpenID成功');
});
router.post(`/applet/getPhoneNumber`, async (ctx) => {
    let body = ctx.request.body;
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if (body.code == null) {
        ctx.body = response.fail('缺少必填字段 code');
        return;
    }
    let res = await getPhoneNumber(body.code);
    if (res.code == 1) {
        ctx.body = response.fail(res.msg);
        return;
    }
    if (typeof (res.data) == "string") {
        res.data = JSON.parse(res.data);
    }
    ctx.body = response.success(res.data, '获取手机号成功');
});

//创建充值订单
router.post(`/applet/recharge/createOrder`, async (ctx) => {
    let body = ctx.request.body;
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if (body.openid == null) {
        ctx.body = response.fail('缺少必填字段 openid');
        return;
    }
    if (body.phone == null) {
        ctx.body = response.fail('缺少必填字段 手机号');
        return;
    }
    if (body.pay_amt == null) {
        ctx.body = response.fail('缺少必填字段 充值金额');
        return;
    }
    if (body.meter_id == null) {
        ctx.body = response.fail('缺少必填字段 电表ID');
        return;
    }
    let order_body = body.order_body == null ? "电表预付费" : body.order_body;
    //根据电表ID查询商户信息
    let sql = `select meter.name as meter_name, merchant.id, merchant.pay_mch_no, merchant.name from meter left join merchant on meter.merchant_id=merchant.id where meter.id=${body.meter_id}`;
    let mch_info = await db.query(sql);
    if (mch_info.length == 0) {
        ctx.body = response.fail('电表不存在');
        return;
    }
    if (mch_info[0].pay_mch_no == null) {
        ctx.body = response.fail('电表未绑定商户');
        return;
    }
    //生成支付订单
    let pay_order = {
        pay_sn: moment().format('YYYYMMDDHHmmssSSS') + Math.floor(Math.random() * 1000000),
        openid: body.openid,
        phone: body.phone,
        mch_name: mch_info[0].name,
        pay_amt: body.pay_amt,
        pay_status: 0,
        pay_type: 0,
        meter_id: body.meter_id,
        order_body: order_body,
        mch_no: mch_info[0].pay_mch_no,
    }
    //创建支付订单
    let res = await lsyPay.applet_pay(pay_order.pay_sn, pay_order.mch_no, pay_order.pay_amt, pay_order.openid, pay_order.order_body);
    if (res.errMsg) {
        ctx.body = response.fail('创建支付订单出错:' + res.errMsg);
        return;
    }
    if (res.return_code != 'SUCCESS') {
        ctx.body = response.fail(res.return_msg);
        return;
    }
    pay_order.create_time = moment().format('YYYY-MM-DD HH:mm:ss');
    let db_result = await db.create('pay_order', pay_order);
    if (db_result instanceof Error) {
        ctx.body = response.fail('写入支付订单失败:' + db_result.message);
        return;
    }
    ctx.body = response.success(res, '创建订单成功');
});
router.all(`/lsy/notify`, async (ctx) => {
    let body = ctx.request.body;
    console.info('接收到支付回调', JSON.stringify(body));
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if (body.result_code == 'PAY_SUCCESS') {
        //支付成功 查询支付流水对应的订单是否存在
        let sql = `select * from pay_order where pay_sn='${body.pay_trace_no}' and pay_status=0`;
        let pay_order = await db.query(sql);
        if (pay_order.length == 0) {
            console.error('支付订单不存在或已支付', JSON.stringify(body));
            ctx.body = { return_code: "SUCCESS", return_msg: "支付订单不存在或已支付" };
            return;
        }
        //查询电表信息
        let meter = await db.findOne('meter', { id: pay_order[0].meter_id });
        if (meter == null) {
            console.error('支付回调查询的电表不存在', '支付订单信息', JSON.stringify(pay_order));
            ctx.body = { return_code: "SUCCESS", return_msg: "电表不存在" };
            return;
        }
        //开始执行事务 更新支订记录表和写入充值记录表
        let sqls = [];
        let recharge_record = {
            meter_id: pay_order[0].meter_id,
            community_path: meter.community_path,
            name: meter.name,
            recharge_time: moment().format('YYYY-MM-DD HH:mm:ss'),
            amt: (pay_order[0].pay_amt / 100).toFixed(2), // 保留两位小数
            phone: pay_order[0].phone,
            openid: pay_order[0].openid,
            pay_sn: pay_order[0].pay_sn,
            e_price: meter.e_price,
            s_price: meter.s_price,
            mch_no: pay_order[0].mch_no,
            mch_name: pay_order[0].mch_name
        };
        if (parseFloat(meter.handing_fee_rate) != null && parseFloat(meter.handing_fee_rate) > 0) {
            recharge_record.handing_fee = parseFloat(pay_order[0].pay_amt) * parseFloat(meter.handing_fee_rate); // 保留两位小数
        } else {
            recharge_record.handing_fee = 0;
        }
        recharge_record.rechagre_num = ((parseFloat(pay_order[0].pay_amt / 100) - parseFloat(recharge_record.handing_fee)) / (parseFloat(meter.e_price) + parseFloat(meter.s_price))).toFixed(2); // 保留两位小数;
        //读取电表余额
        let real_meter_info = await getEMT(meter.mac);
        if (real_meter_info.code != 1) {
            console.error('读取电表余额失败', JSON.stringify(real_meter_info));
            ctx.body = { return_code: "Fail", return_msg: "读取电表余额失败" };
            return;
        }
        let write_num = real_meter_info.data.EME + parseFloat(recharge_record.rechagre_num);//写入电表的电量
        let set_res = await setEME(meter.mac, write_num);
        if (set_res.code != 1) {
            console.error('写入新剩余电量失败', JSON.stringify(set_res));
            //写入重试表  下次上线时重试
            let write_EME_try = {
                mac: meter.mac,
                new_EME: recharge_record.rechagre_num,
                create_time: moment().format('YYYY-MM-DD HH:mm:ss'),
                try_count: 1,
                pay_sn: recharge_record.pay_sn,
            }
            let write_res = await db.create('write_EME_try', write_EME_try);
            if (write_res instanceof Error) {
                console.error('写入重试表失败', write_res.message, JSON.stringify(write_EME_try));
                ctx.body = { return_code: "Fail", return_msg: "写入重试表失败" };
                return;
            }
        } else {
            recharge_record.old_num = real_meter_info.data.EME;//原电量
            recharge_record.new_num = real_meter_info.data.EME + parseFloat(recharge_record.rechagre_num);//新电量
        }

        sqls.push({ sql: `insert into recharge_rec set ?`, param: recharge_record });
        sqls.push({ sql: `update pay_order set pay_status=10, pay_time='${moment().format('YYYY-MM-DD HH:mm:ss')}' where pay_sn='${pay_order[0].pay_sn}'` });
        let res = await db.transaction(sqls);
        if (res instanceof Error) {
            console.error('更新充值记录失败', res.message, JSON.stringify(recharge_record));
            ctx.body = { return_code: "Fail", return_msg: "更新充值记录失败" };
            return;
        }
        console.info('更新充值记录成功', JSON.stringify(recharge_record));
        ctx.body = { return_code: "SUCCESS", return_msg: "成功" };
    }
    else {
        //支付失败
        console.error('接收到未成功的支付通知', JSON.stringify(body));
        ctx.body = { return_code: "SUCCESS", return_msg: "成功" };
    }
});
router.all(`/lsy/refund/notify`, async (ctx) => {
    let body = ctx.request.body;
    console.info('接收到退款回调', JSON.stringify(body));
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if (body.result_code == 'PAY_SUCCESS') {
        //退款成功 查询退款流水对应的订单是否存在
        let sql = `select * from pay_order where pay_sn='${body.pay_trace_no}' and pay_status=0`;
        let pay_order = await db.query(sql);
        if (pay_order.length == 0) {
            console.error('退款订单不存在或已退款', JSON.stringify(body));
            ctx.body = { return_code: "SUCCESS", return_msg: "退款订单不存在或已退款" };
            return;
        }
        //开始执行事务 更新支订记录表和写入充值记录表
        let sqls = [];
        sqls.push({ sql: `update pay_order set pay_status=20, refund_time='${moment().format('YYYY-MM-DD HH:mm:ss')}' where pay_sn='${pay_order[0].pay_sn}'` });
        let res = await db.transaction(sqls);
        if (res instanceof Error) {
            console.error('更新退款记录失败', res.message, JSON.stringify(body));
            ctx.body = { return_code: "Fail", return_msg: "更新退款记录失败" };
            return;
        }
        console.info('更新退款记录成功', JSON.stringify(body));
        ctx.body = { return_code: "SUCCESS", return_msg: "成功" };
    }
    else {
        //退款失败
        console.error('接收到未成功的退款通知', JSON.stringify(body));
        ctx.body = { return_code: "SUCCESS", return_msg: "成功" };
    }
});

export { router };
